<?php

namespace App\Http\Controllers\Admin\Depot;

use App\Exceptions\AppException;
use App\Http\Controllers\Controller;
use App\Models\airline\base\ContainerModel;
use App\Models\DepotBanItemModel;
use App\Models\DepotBanModel;
use App\Models\FlightModel;
use App\Models\OrderModel;
use App\Models\OrderVolumeModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

//入库
class Storage extends Controller
{


    //集运入库
    public function add(Request $request) {
        $params = $request->all();

        $validator = Validator::make($params, [
            'sn' => 'required',
            'storage_weight' => 'required|numeric',
            'place_id' => 'required|integer',
            'volumes' => 'required|array'
        ], [
            'sn.required' => '请填写入仓号',
            'storage_weight.required' => '请填写入库重量',
            'storage_weight.numeric' => '入库重量必须为数字',
            'place_id.required' => '请选择库位',
            'volumes.required' => '请填写体积信息',
            'volumes.array' => '体积信息必须为数组'
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $order = OrderModel::query()->where('sn', $params['sn'])->first();
        if (!$order) {
            return $this->error('入仓单不存在');
        }

        foreach($params['volumes'] as $volume)  {
            $validator = Validator::make($volume, [
                'len' => 'required|numeric',
                'width' => 'required|numeric',
                'height' => 'required|numeric',
                'nums' => 'required|integer',
            ], [
                'len.required' => '请填写长度',
                'width.required' => '请填写宽度',
                'height.required' => '请填写高度',
                'len.numeric' => '长度必须为数字',
                'width.numeric' => '宽度必须为数字',
                'height.numeric' => '高度必须为数字',
                'nums.required' => '请填写数量',
                'nums.integer' => '数量必须为整数'
            ]);
    
            if ($validator->fails()) {
                return $this->error($validator->errors()->first());
            }
        }

        try{
            DB::transaction(function () use ($params, $order) {
                $order->status = OrderModel::STATUS_STORAGE;
                $order->storage_weight = $params['storage_weight'];
                $order->place_id = $params['place_id'];
                $order->loadless_weight = $params['storage_weight'];
                $order->storage_time = date('Y-m-d H:i:s');
                $order->surplus_weight = $params['storage_weight'];
                $order->save();

                $storage_volume = 0; $storage_big_pkgs = 0;
                foreach($params['volumes'] as $volume) {
                    $model = new OrderVolumeModel();
                    $model->order_id = $order->id;
                    $model->len = $volume['len'];
                    $model->width = $volume['width'];
                    $model->height = $volume['height'];
                    $model->nums = $volume['nums'];
                    $model->save();

                    $storage_volume += $volume['len'] * $volume['width'] * $volume['height'] * $volume['nums'];
                    $storage_big_pkgs += $volume['nums'];
                }

                $order->storage_volume = round($storage_volume / 1000000, 2);
                $order->storage_big_pkgs = $storage_big_pkgs;
                $order->save();
            });
        } catch(\Exception $e) {
            return $this->error($e->getMessage());
        }

        return $this->success();

    }

    //上板列表
    public function boards(Request $request) {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 10);
        $container_ids = $request->input('container_ids', []);
        $codes = $request->input('codes', []);
        $ban_id = $request->input('ban', 0);
        $create_start = $request->input('create_start', '');
        $create_end = $request->input('create_end', '');

        $query = DepotBanModel::query();

        if($ban_id) {
            $query->whereIn('container_id', function($query) use ($ban_id) {
                $query->select('id')
                    ->from((new ContainerModel())->getTable())
                    ->where('ban_id', $ban_id);
            });
        }

        if(is_array($container_ids) && !empty($container_ids)) {
            $query->whereIn('container_id', $container_ids);
        }

        if(is_array($codes) && !empty($codes)) {
            $query->whereIn('container_id', function($query) use ($codes) {
                $query->select('id')
                    ->from((new ContainerModel())->getTable())
                    ->whereIn('code_id', $codes);
            });
        }

        if($create_start && $create_end){
            $query = $query->whereBetween('created_at', [$create_start, $create_end]);
        }

        $total = $query->count();
        $list = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $res = $list->map(function($item) {
            return [
                'id' => $item->id,
                'container_idx' => $item->container->container_id ?? '',
                'ban' => $item->container->ban->name ?? '',
                'code' => $item->container->code->code ?? '',
                'created_at' => $item->created_at->toDateTimeString(),
                'create_user' => $item->create_admin->staff->name ?? ''
            ];
        });

        return $this->success([
            'list' => $res,
            'total' => $total,
        ]);

    }

    //上板
    public function load_board(Request $request) {
        $params = $request->all();

        $id = $params['id'] ?? 0;

        $validator = Validator::make($params, [
            'ban_id' => 'required|integer',
            'container_id' => 'required|integer',
            'order_sn' => 'required',
            'nums' => 'required|integer',
            'weight' => 'required|numeric',
        ], [
            'ban_id.required' => '请选择板型',
            'container_id.required' => '请选择集装器',
            'order_sn.required' => '请填写入仓号',
            'nums.required' => '请填写件数',
            'weight.required' => '请填写重量',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $container = ContainerModel::where('ban_id', $params['ban_id'])
            ->find($params['container_id']);

        if (!$container) {
            return $this->error('集装器错误');
        }

        $order = OrderModel::where('sn', $params['order_sn'])->first();
        if (!$order) {
            return $this->error('入仓号不存在');
        }

        if($order->cargo_status != OrderModel::CARGO_STATUS_FILL) {
            return $this->error('该入仓单没有提单号');
        }

        $flight = $order->flight;
        if(!$flight) {
            return $this->error('入仓单航班运力错误');
        }

        if($flight->status != FlightModel::STATUS_COMPLETED) {
            return $this->error('航班未完成配舱');
        }

        $ban_ids = $flight->bans->pluck('ban_id')->toArray();
        if(!in_array($params['ban_id'], $ban_ids)) {
            return $this->error('提单板型不匹配');
        }

        $auth = $request->get('auth');

        DB::beginTransaction();
        try{
            $find = DepotBanModel::where('container_id', $params['container_id'])->first();
            if($id != 0) {
                $depot_ban = DepotBanModel::find($id);
                if(!$depot_ban){
                    throw new AppException('上板记录不存在');
                }
            }else if($find){
                $depot_ban = $find;
            } else {
                $depot_ban = new DepotBanModel();
                $depot_ban->container_id = $params['container_id'];
                $depot_ban->created_admin_id = $auth->id;
                $depot_ban->flight_id = $order->flight_id;
                $depot_ban->save();
            }

            $depot_order = new DepotBanItemModel();
            $depot_order->depot_ban_id = $depot_ban->id;
            $depot_order->order_id = $order->id;
            $depot_order->nums = $params['nums'];
            $depot_order->weight = $params['weight'];
            $depot_order->remark = $params['remark'] ?? '';
            $depot_order->save();

            if($params['nums'] > $order->loadless_big_pkgs) {
                throw new AppException('件数不能小于剩余件数');
            }


            if($params['weight'] > $order->loadless_weight) {
                throw new AppException('重量不能小于剩余重量');
            }

            $order->loadless_big_pkgs = DB::raw("loadless_big_pkgs-{$params['nums']}");
            $order->loadless_weight = DB::raw("loadless_weight-{$params['weight']}");
            $order->save();
            DB::commit();
        } catch(\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }

        return $this->success($depot_ban->id);
    }

    //上板记录
    public function load_history(Request $request) {
        $page = $request->input('page', 1);
        $limit = $request->input('limit', 10);
        $id = $request->input('id', 0);

        $depot_ban = DepotBanModel::find($id);
        if(!$depot_ban) {
            return $this->error('上板记录不存在');
        }

        $query = DepotBanItemModel::query()->where('depot_ban_id', $id);
        $total = $query->count();
        $list = $query
            ->offset(($page-1) * $limit)
            ->limit($limit)
            ->orderBy('id', 'desc')
            ->get();

        $res = $list->map(function($item) {
            return [
                'id' => $item->id,
                'order_sn' => $item->order->sn ?? '',
                'take_order_sn' => $item->order->take_order->sn ?? '',
                'big_pkgs' => $item->order->big_pkgs ?? '',
                'storage_weight' => $item->order->storage_weight ?? '',
                'loadless_big_pkgs' => $item->order->loadless_big_pkgs ?? 0,
                'loadless_weight' => $item->order->loadless_weight ?? 0,
                'nums' => $item->nums,
                'weight' => $item->weight,
                'remark' => $item->remark
            ];
        });

        return $this->success([
            'list' => $res,
            'total' => $total,
        ]);
    }

    //撤销上板
    public function cancel($id) {
        $depot_ban = DepotBanItemModel::find($id);
        if(!$depot_ban) {
            return $this->error('上板记录不存在');
        }

        DB::transaction(function () use ($depot_ban) {
            $depot_ban->delete();

            $order = $depot_ban->order;
            if($order){
                $order->loadless_big_pkgs = DB::raw("loadless_big_pkgs+{$depot_ban->nums}");
                $order->loadless_weight = DB::raw("loadless_weight+{$depot_ban->weight}");
                $order->save();
            }
        });


        return $this->success();
    }

    //获取提单号
    public function get_order_sn(Request $request) {
        $order_sn = $request->input('order_sn');
        if(!$order_sn) {
            return $this->error('入仓号不能为空');
        }

        $order = OrderModel::where('sn', $order_sn)->first();
        if (!$order) {
            return $this->error('入仓号不存在');
        }

        return $this->success([
            'take_order_sn' => $order->take_order->sn ?? '',
            'big_pkgs' => $order->big_pkgs,
            'loadless_big_pkgs' => $order->loadless_big_pkgs,
            'weight' => $order->storage_weight,
            'loadless_weight' => $order->loadless_weight
        ]);
    }

    /**
     * Notes:总上板件数和未上板件数
     * User: xiangzi
     * Date: 2024/10/17
     * Time: 上午11:28
     * @return \Illuminate\Http\JsonResponse
     */
    public function load_info(Request $request)
    {
        $order_sn = $request->input('order_sn');
        if(!$order_sn) {
            return $this->error('入仓号不能为空');
        }

        $order = OrderModel::where('sn', $order_sn)->first();
        if (!$order) {
            return $this->error('入仓号不存在');
        }

        $return = ['big_pkgs' => $order->big_pkgs, 'loadless_big_pkgs' => $order->loadless_big_pkgs];
        return $this->success($return);
    }

    /**
     * Notes:pda已上板入仓单
     * User: xiangzi
     * Date: 2024/10/21
     * Time: 下午5:10
     * @return \Illuminate\Http\JsonResponse
     */
    public function load_record(Request $request)
    {
        $container_id = $request->input('id', 0);

        $return = ['list' => [], 'total_nums' => 0, 'total_weight' => 0];

        $find = DepotBanModel::where('container_id', $container_id)->first();
        if($find){
            $items = DepotBanItemModel::where('depot_ban_id', $find->id)->get();
            if($items){
                $list = $items->map(function($item){
                    return [
                        'order_sn' => $item->order->sn ?? '',
                        'weight' => $item->weight,
                        'nums' => $item->nums,
                        'big_pkgs' => $item->order->big_pkgs ?? 0,
                    ];
                });

                $return = [
                    'list' => $list,
                    'total_nums' => $items->sum('nums'),
                    'total_weight' => $items->sum('weight'),
                ];
            }
        }

        return $this->success($return);

    }

}
